<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #app{
            border: 1px solid #cccccc;
            padding: 10px;
        }
        .box{
            border: 1px solid #cccccc;
            margin-left: 50px;
            padding: 10px;
        }
        p{
            padding-left: 20px;
        }
    </style>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="app">
        <h3>父组件范围</h3>
        <p>msg:{{ msg }}</p>
        <p>user:{{ user }}</p>

        <!-- 
            1、页面开发时，子组件标签确实需要定义于父组件容器内，
               但子组件对应的容器结构和父组件的容器结构是相互独立的 
            2、组件标签被渲染完成时将被替换删除，由组件模板进行整体展示
            3、因为组件标签渲染完成后会被删除，所以开发时定义在组件标签上的属性，vue会默认将其传递到子组件根元素上
            4、所以在子组件标签上通过 v-bind 完成的自定义属性绑定取值对应父组件容器范围,
               渲染后绑定数据会传递到子组件容器的根元素上，以此可以实现数据跨组件传递
            5、vue在子组件容器渲染过程中，会将自定义的绑定属性传递到实例属性 $attrs 中，因为属于JS操作阶段，所以不会进行字符串化
            6、因此子组件语法规则中，可以直接通过 this.$attrs 进行绑定属性的取值操作
            7、vue提供组件配置属性 props 用于主动从 $attrs 提取需要数据变量并完成仓库变量定义操作
                + props 为vue实例的数据仓库，该仓库除只能用于读取外，其他操作和data数据仓库一致
                + props 完成属性拦截和调用后，该属性在页面和$attrs都将被删除
        -->
        <!--     
            - 技术实现：属性绑定，数据拦截
            - 详细描述：以属性绑定的方式将传递的数据绑定在子组件标签上，在子组件对象中 以属性 props 方式进行 绑定属性的拦截
         -->
        <p class="aaa" v-bind:msg="msg"></p>
        <child-one v-bind:class=" 'aaa' " 
            v-bind:msg="msg"
            v-bind:user="user"
            v-bind:flag="flag"
        ></child-one>
    </div>
</body>
<script type="text/x-template" id="one">
    <div class="box" ref="one">
        <h3>子组件范围</h3>
        <p>msg:{{ msg }}</p>
        <p>user:{{ user }}</p>
    </div>
</script>
<script>
    // 父组件向子组件的数据传递

    // 技术过渡 step1、属性加载  - 存在数据传递的各种问题
    // Vue.component("ChildOne",{
    //     template:"#one",
    //     data(){
    //         return {
    //             msg:"",
    //             user:{}
    //         }
    //     },
    //     mounted() {
    //         console.log( this.$refs.one.getAttribute("msg") );
    //         console.log( this.$refs.one.getAttribute("user") );

    //         this.msg = this.$refs.one.getAttribute("msg");
    //         this.user = this.$refs.one.getAttribute("user") 
    //     },
    // })

    // 技术过渡 step2、vue组件内置实例属性 $attrs
    // Vue.component("ChildOne",{
    //     template:"#one",
    //     data(){
    //         return {
    //             msg:"",
    //             user:{}
    //         }
    //     },
    //     mounted() {
    //         console.log( this.$attrs.msg );
    //         console.log( this.$attrs.user );

    //         this.msg = this.$attrs.msg;
    //         this.user = this.$attrs.user; 
    //     },
    // })

    // 技术过渡 step3、绑定属性的拦截定义 - 简化取值代码
    Vue.component("ChildOne",{
        template:"#one",
        props:["msg","user"]
    })

    new Vue({
        el:"#app",
        data:{
            msg:"父组件变量MSG",
            user:{
                name:"tom"
            },
            flag:true
        }
    })
</script>
</html>